Cloud Composer で GCS から SFTP サーバ にファイル転送してみた 〜鍵認証編〜
本記事はGCP(Google Cloud Platform) Advent Calendar 2022 18日目の記事です。
こんにちは!エノカワです。
Cloud Composer は、Apache Airflow で構築されたフルマネージドのワークフローオーケストレーションサービスです。
Apache Airflow のオープンソース プロジェクトを基に構築されており、Python プログラミング言語を使用して動作します。
下記エントリでは、Cloud Composer で Cloud Storage にあるファイルをSFTPサーバに転送するワークロードを紹介しました。
前回はパスワード認証でしたが、今回は鍵認証で同様のワークロードを試してみたのでご紹介します。
なお、[SFTPサーバをたてる]、[Cloud Composer 環境を作成]の箇所は前回と同様となりますので、詳細については上記エントリを参照ください。
SFTPサーバをたてる
ファイル転送先のSFTPサーバをたてます。
前回と同様、test-sftp-server
という名前で、東京リージョン、最小のマシン構成を選択し、他はデフォルトのままで作成しました。
[SSH]リンクからインスタンスに接続し、sftp_user
ユーザーの追加とupload
フォルダの作成もしておきます。
転送ファイルをアップロード
SFTPサーバに転送するファイルを Cloud Storage にアップロードします。
今回はtest-gcs-sftp
バケットにfile_key.txt
をアップロードしました。
鍵認証の設定
SFTPサーバで鍵認証するための設定を行います。
SSH鍵ペアを生成
Cloud Shell からssh-keygen
コマンドを使用して、SSH鍵ペアを生成します。
$ ssh-keygen -t rsa -m PEM -N "" -C "sftp_user@test-sftp-server" -f test_sftp Generating public/private rsa key pair. Your identification has been saved in test_sftp Your public key has been saved in test_sftp.pub The key fingerprint is: SHA256:S3nJDUkM3TR6fY0V3OyzfJbaChifZ18C5Q0o2gZqLkM sftp_user@test-sftp-server The key's randomart image is: +---[RSA 3072]----+ | .+.oo .o+| | .oo.+ ++| | . = o =.o| | . * * o =.| | E o S.* o o =| | . o . ++ .. +o| | o . .. + o+.o| | o +..o.| | ... | +----[SHA256]-----+
秘密鍵と公開鍵が作成されました。
$ ls test_sftp test_sftp.pub
公開鍵test_sftp.pub
を開いて、内容をコピーします。
公開鍵を登録
test-sftp-server
インスタンスの編集画面に入り、[SSH 認証鍵]項目に先ほどコピーした公開鍵の内容を登録します。
これでSFTPサーバの準備が整いました。
Secret Manager に 秘密鍵を保存
Cloud Composer から SFTP サーバにアクセスする際に使用する秘密鍵を Secret Manager に保存します。
以下のコマンドで、シークレットを作成し、秘密鍵を保管するシークレットとバージョンを作成します。
gcloud secrets create sftp_user-key gcloud secrets versions add sftp_user-key --data-file="./test_sftp"
作成したシークレットにアクセスするために、Compute Engine のデフォルトのサービスアカウントに Secret Manager のシークレット アクセサー
(roles/secretmanager.secretAccessor
)のロールを付与しておきます。
gcloud secrets add-iam-policy-binding sftp_user-key \ --member="serviceAccount:{PROJECT_ID}-compute@developer.gserviceaccount.com" \ --role="roles/secretmanager.secretAccessor"
※プロジェクトIDの箇所は{PROJECT_ID}
に置き換えています。
この後に作成する Cloud Composer では Compute Engine のデフォルトのサービスアカウントを使用します。
Cloud Composer 環境を作成
DAGを動かす Cloud Composer 環境を作成します。
前回と同様、test-composer
という名前で、東京リージョン、最新のイメージバージョンを選択し、サービスアカウントなど他はでデフォルトのままで作成しました。
今回もgcs_to_sftpオペレータを使用しますので、apache-airflow-providers-sftp
パッケージもインストールしておきまます。
DAG を作成
Cloud Composer 環境で実行する DAGを作成します。
以下の記事を参考にさせていただきました!
- AirflowのConnectionのパラメータを既存のDBから設定する方法 | takemikami's note
- シークレットマネージャを使ってCloud Composerで機密情報を扱う - Qiita
転送元にはtest-gcs-sftp
バケットとアップロードしたfile_key.txt
ファイル、転送先にはtest-sftp-server
インスタンスに作成したupload
フォルダを指定しました。
GCSToSFTPOperatorのSFTPサーバへの接続IDsftp_conn_id
には Secret Manager から取得した秘密鍵を設定した接続IDgcs_sftp
を指定しています。
import json import os from datetime import datetime from google.cloud import secretmanager_v1beta1 from airflow import DAG from airflow.models import Connection from airflow.providers.google.cloud.transfers.gcs_to_sftp import GCSToSFTPOperator # Secret Managerから秘密鍵を取得 client = secretmanager_v1beta1.SecretManagerServiceClient() name = client.secret_version_path("{PROJECT_ID}", "sftp_user-key", "latest") response = client.access_secret_version(name) private_key = response.payload.data.decode("UTF-8") # Airflow接続を作成 extra_secret = { "private_key": private_key, } conn = Connection( conn_id="gcs_sftp", conn_type="sftp", host="test-sftp-server", login="sftp_user", port=22, extra=json.dumps(extra_secret), ) os.environ["AIRFLOW_CONN_GCS_SFTP"] = conn.get_uri() with DAG( dag_id="example_gcs_to_sftp_key", start_date=datetime.now(), schedule_interval=None, ) as dag: copy_file_from_gcs_to_sftp = GCSToSFTPOperator( task_id="file-copy-gsc-to-sftp_key", sftp_conn_id="gcs_sftp", source_bucket="test-gcs-sftp", source_object="file_key.txt", destination_path="/home/sftp/upload/", )
※プロジェクトIDの箇所は{PROJECT_ID}
に置き換えています。
DAGフォルダにファイルをアップロードしてDAGをデプロイします。
DAG を実行
デプロイしたDAGを実行してみましょう。
前回と同様、DAG詳細画面右上の[再生マーク]ボタンからTrigger DAGをクリックして、手動でDAGをトリガーします。
DAGが実行され、file-copy-gsc-to-sftp_key
タスクが緑色のsuccess
でマークされました。
転送ファイルを確認
SFTPサーバにファイルが転送されているか確認してみましょう。
test-sftp-server
インスタンスに接続して、upload
フォルダ配下をチェックします。
file_key.txt
ファイルが居てました。
ファイル転送成功です!
まとめ
以上、Cloud Composer で GCS から 鍵認証で SFTP サーバ にファイル転送してみました。
前回のパスワード認証と同じく、gcs_to_sftp
オペレータを使用するだけというシンプルなDAGですが、今回は鍵認証のために秘密鍵へのアクセスが必要です。
秘密鍵 の管理を Secret Manager で行い、DAGファイル内で SFTPサーバへの接続ID 組み立てるというのが今回のポイントでした。
今回は Secret Manager API を直接使用しましたが、Secret Manager をバックエンドに構成して変数としてシークレットにアクセスする方法もありますので、次回はこちらを紹介したいと思います!
参考
- airflow.providers.google.cloud.transfers.gcs_to_sftp — apache-airflow-providers-google Documentation
- How to Setup a sFTP Server in Google Cloud Platform and Restrict Access | by Rubens Zimbres | Medium
- シークレットの作成とアクセス | Secret Manager のドキュメント | Google Cloud
- IAM を使用したアクセス制御 | Secret Manager のドキュメント | Google Cloud
- Managing Connections — Airflow Documentation
- AirflowのConnectionのパラメータを既存のDBから設定する方法 | takemikami's note
- シークレットマネージャを使ってCloud Composerで機密情報を扱う - Qiita